# encoding: UTF-8

import os

def gen(packages, conf):
    if not os.path.exists(conf['javaOutDir']):
        print 'javaOutDir no exists'
        exit(1)

    _initDir(conf)
    _genJfinalControl(packages, conf)
    _genIntegerFace(packages, conf)
    _genBean(packages, conf)

def _initDir(conf):
    '''初始化目录'''
    outDir = conf['javaOutDir']

    dir = outDir + conf['jfinalControllerPack'].replace('.', '/') + '/'
    if not os.path.exists(dir):
        os.makedirs(dir)

    dir = outDir + conf['controllerInterfacePack'].replace('.', '/') + '/'
    if not os.path.exists(dir):
        os.makedirs(dir)

    dir = outDir + conf['controllerBeanPack'].replace('.', '/') + '/'
    if not os.path.exists(dir):
        os.makedirs(dir)

def _genJfinalControl(packages, conf):
    '''
    生产 jfinal control代码
    :param packages:
    :param conf:
    :return:
    '''

    controlPackage   = conf['jfinalControllerPack']
    outDir           = conf['javaOutDir']
    controlDir       = outDir + controlPackage.replace('.', '/') + '/'

    for pack in packages:
        package         = pack['package']
        comment         = pack['comment']
        javaFileContent = 'package ' + controlPackage + ';\n'

        javaFileContent += 'import java.util.*;\n'
        javaFileContent += 'import com.alibaba.fastjson.JSON;\n'
        javaFileContent += 'import ' + conf['controllerBeanPack'] + '.*;\n'
        javaFileContent += 'import com.jfinal.core.Controller;\n'
        javaFileContent += 'import ' + conf['controllerInterfacePack'] + '.I' + package + ';\n'
        javaFileContent += 'import ' + conf['controllerImplPack'] + '.' + package + 'Impl;\n'

        javaFileContent += '/**\n'
        javaFileContent += '*' + comment + '\n'
        javaFileContent += '*/\n'
        javaFileContent += 'public class ' + package + ' extends Controller {\n'
        javaFileContent += '\tprivate I' + package + ' ' + _getName(package) + ' = new ' + package + 'Impl();\n'

        for protocol in pack['protocls']:
            # 生成注释
            javaFileContent += '\t\t/**\n'
            javaFileContent += '\t\t*' + protocol['comment'] + '\n'
            for param in protocol['params']:
                javaFileContent += '\t\t* param:' + param['name'] + ' type:' + param['type'] + ' 描述:' + param['comment'] + '\n'
            javaFileContent += '\t\t*/\n'

            # 生成方法
            javaFileContent += '\tpublic void ' + protocol['method'] + '(){\n'

            # 生成获取参数
            methodParams = []
            for param in protocol['params']:
                methodParams.append(param['name'])
                if param['type'] == 'Integer' or param['type'] == 'int':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param['name'] + ' = ' + 'getParaToInt("' + param[
                        'name'] + '");\n'
                elif param['type'] == 'String':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param['name'] + ' = ' + 'getPara("' + param[
                        'name'] + '");\n'
                elif param['type'] == 'boolean' or param['type'] == 'Boolean':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param['name'] + ' = ' + 'getParaToBoolean("' + param[
                        'name'] + '");\n'
                elif param['type'] == 'long' or param['type'] == 'Long':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param['name'] + ' = ' + 'getParaToLong("' + param[
                        'name'] + '");\n'
                elif param['type'] == 'Double' or param['type'] == 'double':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param[
                        'name'] + ' = ' + 'Double.parseDouble(getPara("' + param['name'] + '"));\n'
                elif param['type'] == 'Float' or param['type'] == 'float':
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param[
                        'name'] + ' = ' + 'Float.parseFloat(getPara("' + param['name'] + '"));\n'
                elif param['type'].startswith("List") or param['type'].startswith("list"):
                    listType = param['type'][5:-1]
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param['name'] + ' = ' + 'JSON.parseArray(getPara("' + \
                                       param['name'] + '"), ' + listType + '.class);\n'
                elif param['type'].startswith("Map") or param['type'].startswith("map"):
                    javaFileContent += '\t\t Map ' + param['name'] + ' = ' + 'JSON.parseObject(getPara("' + param[
                        'name'] + '"));\n'
                else:
                    javaFileContent += '\t\t ' + param['type'] + ' ' + param[
                        'name'] + ' = ' + 'JSON.parseObject(getPara("' + param['name'] + '"), ' + param[
                                           'type'] + '.class);\n'

            # 生成方法内容
            javaFileContent += '\t\t ' + protocol['return'] + ' obj = ' + _getName(package) + '.' + protocol[
                'method'] + '(' + ", ".join(methodParams) + ');\n'
            javaFileContent += '\t\t ControllerResultBean result = new ControllerResultBean(obj);\n'
            javaFileContent += '\t\t renderJson(result);\n'

            javaFileContent += '\t}\n\n'

        javaFileContent += '}'

        javaFile = open(controlDir + package + '.java', 'w')
        javaFile.writelines(javaFileContent)

def _genIntegerFace(packages, conf):
    '''
    生成业务层接口
    :param packages:
    :param conf:
    :return:
    '''
    controlPackage   = conf['controllerInterfacePack']
    outDir           = conf['javaOutDir']
    controlDir = outDir + controlPackage.replace('.', '/') + '/'

    for pack in packages:
        comment         = pack['comment']
        package         = pack['package']
        javaFileContent = 'package ' + controlPackage + ';\n'
        javaFileContent += 'import ' + conf['controllerBeanPack'] + '.*;\n'
        javaFileContent += 'import java.util.*;\n'
        javaFileContent += '/**\n'
        javaFileContent += '* ' + comment + '\n'
        javaFileContent += '*/\n'
        javaFileContent += 'public interface I' + package + ' {\n'

        for protocol in pack['protocls']:
            # 生成注释
            javaFileContent += '\t/**\n'
            javaFileContent += '\t* ' + protocol['comment'] + '\n'
            for param in protocol['params']:
                javaFileContent += '\t* param:' + param['name'] + ' type:' + param['type'] + ' 描述:' + param[
                    'comment'] + '\n'
            javaFileContent += '\t*/\n'

            # 生成获取参数
            methodParams = []
            for param in protocol['params']:
                methodParams.append(param['type'] + " " + param['name'])

            # 生成方法
            javaFileContent += '\tpublic ' + protocol['return'] + ' ' + protocol['method'] + '(' + ", ".join(
                methodParams) + ');\n'

        javaFileContent += '}'

        javaFile = open(controlDir + 'I' + package + '.java', 'w')
        javaFile.writelines(javaFileContent)

def _genBean(packages, conf):
    '''
    生成Bean
    :param packages:
    :param conf:
    :return:
    '''
    package = conf['controllerBeanPack']
    outDir  = conf['javaOutDir']
    beanDir = outDir + package.replace('.', '/') + '/'

    for pack in packages:
        beans = pack['beans']
        for bean in beans:
            fileContent = 'package ' + package + ';\n\n'
            fileContent += 'import java.util.*;\n\n'
            fileContent += '/**\n'
            fileContent += '*' + bean['comment'] + '\n'
            fileContent += '*/\n\n'
            fileContent += 'public class ' + bean['name']
            if bean['extends']:
                fileContent += ' extends ' + bean['extends']
            fileContent += ' {\n'

            # 生成属相
            for param in bean['params']:
                fileContent += '\t//' + param['comment'] + '\n'
                fileContent += '\tprivate ' + param['type'] + ' ' + param['name'] + ';\n'
            fileContent += '\n'

            # 生成GET和SET方法
            for param in bean['params']:
                fileContent += '\tpublic ' + param['type'] + ' get' + _getJavaMethodName(param['name']) + '(){\n'
                fileContent += '\t\treturn ' + param['name'] + '; \n'
                fileContent += '\t}\n'
                fileContent += '\tpublic void set' + _getJavaMethodName(param['name']) + '(' + param['type'] + ' ' + param[
                    'name'] + '){\n'
                fileContent += '\t\tthis.' + param['name'] + ' = ' + param['name'] + '; \n'
                fileContent += '\t}\n'

            fileContent += '}\n';
            javaFile = open(beanDir + bean['name'] + '.java', 'w')
            javaFile.writelines(fileContent)
            javaFile.close()

def _getJavaMethodName(name):
    return name[0:1].upper() + name[1:]

def _getName(name):
    return name[0:1].lower() + name[1:]